import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;

/*
 * This class is responsible for logging all the necessary details within the software.
 * 
 * 		1. The first log file "System-Status.log", acts as a history of all the details regarding the server and its processors.
 * 		2. The second log file "System-Trace.log", logs every detail of the system procedure (Sentences given to it by other classes).
 */

public class ApplicationLogger implements Runnable, IApplicationLogger 
{
	protected volatile IServerCluster serverCluster = null;
	protected volatile IServerClusterUsageData sC_UsageData = null;
	protected volatile ApplicationPowerMonitor monitor = null;
	protected volatile Boolean running = null;
	
	private BufferedWriter systemStatusLogger = null;
	
	public ApplicationLogger(IServerCluster serverCluster, IServerClusterUsageData sC_UsageData
			, Boolean running, ApplicationPowerMonitor monitor)
	{
		this.serverCluster = serverCluster;
		this.sC_UsageData = sC_UsageData;
		this.monitor = monitor;
		this.running = running;
		
		try {
			String date_fileName = String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)) + "-"
									+ String.valueOf(Calendar.getInstance().get(Calendar.MONTH) + 1) + "-"
									+ String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
			
			systemStatusLogger = new BufferedWriter(new FileWriter(new File("System-Status-" + date_fileName + ".log"),true));
		} catch (IOException e) {
			System.out.println("Error in creating log files !!");
			e.printStackTrace();
		}
	}
	
	public void run() 
	{
		while(running)
		{
			// Update the system status every 5 seconds
			
			updateSystemStatus();
			
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	private void updateSystemStatus()
	{
		// Update the System-Status log file with details about all the servers
		
		writeToSystemStatusFile("System Status @ " + Calendar.getInstance().getTime().toString() + "\n");
		
		// Info about the overall system status
		
		writeToSystemStatusFile("No of Server: " + serverCluster.getServerCount());
		
		try {
			writeToSystemStatusFile("Total Power Consumption (Watt-Hour): " + monitor.getText_totalPc().getText());
			writeToSystemStatusFile("Total No of Running Job: " + monitor.getText_totalRunningJob().getText());
			writeToSystemStatusFile("Total No of Unprocessed Jobs: " + monitor.getText_totalDueJob().getText());
		} catch(Exception e) {
			System.out.println("Error in extracting certain data ... but still continuing !!");
			e.printStackTrace();
		}
		
		// Info about individual servers
		
		for(int i=0;i<serverCluster.getServerCount();i++)
		{
			IServer tempServer = serverCluster.getServer(i);
			
			writeToSystemStatusFile("\n-------- Information for Server: " + tempServer.getServerID() + " --------\n");
			writeToSystemStatusFile("Server Description: " + tempServer.getServerDesc());
			writeToSystemStatusFile("Processor Count: " + tempServer.getNPUCount());
			writeToSystemStatusFile("Processor Core Count: " + tempServer.getNPECount());
			writeToSystemStatusFile("Total Server Memory (KB): " + tempServer.getServerMemory());
			writeToSystemStatusFile("Current Power Consumption (Watt-Hour): " + tempServer.getPowerConsumption());
			writeToSystemStatusFile("Server Power factor: " + tempServer.getPowerFactor());
			writeToSystemStatusFile("Maximum Consumable Power (Watt-Hour): " + tempServer.getMaxPower());
			writeToSystemStatusFile("Server Capability Value: " + sC_UsageData.getServerCapability(i));
			writeToSystemStatusFile("Server Average Power Consumption (Watt-Hour): " + sC_UsageData.getServerAverage(i));
			writeToSystemStatusFile("No of running Jobs: " + tempServer.getRunningJobCount());
			writeToSystemStatusFile("No of Unprocessed Jobs: " + tempServer.getDueJobCount());
			
			// About individual Processing Units
			
			for(int j=0;j<tempServer.getNPUCount();j++)
			{
				IProcessingUnit tempProcessingUnit = tempServer.getProcessingUnit(j);
				
				writeToSystemStatusFile("\t#### Information for Processing Unit: " + tempProcessingUnit.getProcessorID() + " ####");
				writeToSystemStatusFile("\t\tProcessor Total Memory (KB): " + tempProcessingUnit.getTotalMemory());
				writeToSystemStatusFile("\t\tProcessor Free Memory (KB): " + tempProcessingUnit.getFreeMemory());
				writeToSystemStatusFile("\t\tProcessor Power Consumption (Watt-Hour): " + tempProcessingUnit.getPowerConsumption());
				writeToSystemStatusFile("\t\tNo of running Jobs: " + tempProcessingUnit.getRunningJobCount());
				writeToSystemStatusFile("\t\tProcessor State: " + tempProcessingUnit.getSystemState());
			}
		}
		
		writeToSystemStatusFile("----------------\n");
	}
	
	private void writeToSystemStatusFile(String msg)
	{
		try {
			systemStatusLogger.write(msg);
			systemStatusLogger.newLine();
		} catch (IOException e) {
			System.out.println("Error, Could not write to System-Status log file !!");
			e.printStackTrace();
		}
	}
}
